/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.terminal_reason;

import picounit.Instrumentation;

import java.util.HashSet;
import java.util.Set;

public class ReasonRegistryImpl implements ReasonRegistry {
	private static final int DISTANCE_TO_CALLER = 4;

	private final Set<String> testMethodsWithReason = new HashSet<String>();
	private final Set<String> reasonEvaluationLines = new HashSet<String>();

	private final Instrumentation instrumentation;
	
	public ReasonRegistryImpl(Instrumentation instrumentation) {
		this.instrumentation = instrumentation;
	}

	public void registerReason(String className, String methodName, int lineNumberOfEvaluator) {
		System.out.println("RegisterReason: " + className + "." + methodName + ": " + lineNumberOfEvaluator);

		testMethodsWithReason.add(createKey(className, methodName));
		reasonEvaluationLines.add(createKey(className, methodName, lineNumberOfEvaluator));
	}

	public boolean reasonOccursNext() {
		if (reasonEvaluationLines.size() == 0 || !anyReasonInCurrentTest()) {
			return false;
		}

		StackTraceElement stackTraceElement = new Throwable().getStackTrace()[DISTANCE_TO_CALLER];

		return reasonEvaluationLines.contains(
			createKey(stackTraceElement.getClassName(), stackTraceElement.getMethodName(),
				stackTraceElement.getLineNumber()));
	}

	private boolean anyReasonInCurrentTest() {
		return testMethodsWithReason.contains(
			createKey(instrumentation.currentTestClass(), instrumentation.currentTestName()));
	}

	private String createKey(String className, String methodName) {
		return className + "." + methodName;
	}

	private String createKey(String className, String methodName, int lineNumberOfEvaluator) {
		return createKey(className, methodName) + ":" + lineNumberOfEvaluator;
	}
}
